package com.acando.feide;

import java.io.File;
import java.io.FileFilter;

import javax.xml.transform.stream.StreamSource;

import com.acando.feide.utils.AppException;

import net.sf.saxon.s9api.Processor;
import net.sf.saxon.s9api.QName;
import net.sf.saxon.s9api.SaxonApiException;
import net.sf.saxon.s9api.Serializer;
import net.sf.saxon.s9api.XdmAtomicValue;
import net.sf.saxon.s9api.XsltCompiler;
import net.sf.saxon.s9api.XsltExecutable;
import net.sf.saxon.s9api.XsltTransformer;

public class Transformer {

    // Directory where input file(s) are located
    File inDir;
    // Main input xml file
    String mainFileName;
    // Name of optional extra input xml file. If this file is needed or not is defined in the XSL file
    String extraFileName;
    // The XSL transform file to use in this transformation
    File xslFile;

    public Transformer(File inDir, String mainFileName, String extraFileName, File xslFile) throws AppException {
        super();
        this.inDir = inDir;
        this.mainFileName = mainFileName;
        File main = new File(inDir.getName() + "/" + mainFileName);
        if (!main.exists()) {
            throw new AppException("Missing input main file '" + main + "'");
        }
        this.extraFileName = extraFileName;
        this.xslFile = xslFile;
    }

    /**
     * Do a XSL transform. The result is written to a file named 'feide.xml'
     * @throws AppException 
     */
    public void transform() throws AppException {
        Processor proc = new Processor(false);
        XsltCompiler comp = proc.newXsltCompiler();
        XsltExecutable exp;
        try {
            exp = comp.compile(new StreamSource(xslFile));
            XsltTransformer trans = exp.load();
            for (File file : inDir.listFiles(new FileFilter() {

                @Override
                public boolean accept(File pathname) {
                    if (pathname.isDirectory()) {
                        return false;
                    }
                    String name = pathname.getName().toLowerCase();
                    return name.endsWith("xml");
                }
            })) {
                if (file.getName().equalsIgnoreCase(mainFileName)) {
                    trans.setParameter(new QName("mainFile"),
                            new XdmAtomicValue(inDir.getName() + "/" + file.getName()));
                }
                if (file.getName().equalsIgnoreCase(extraFileName)) {
                    trans.setParameter(new QName("extraFile"), new XdmAtomicValue(inDir.getName() + "/"
                            + file.getName()));
                }
            }
            Serializer out = new Serializer();
            out.setOutputProperty(Serializer.Property.METHOD, "xml");
            out.setOutputProperty(Serializer.Property.INDENT, "yes");
            out.setOutputFile(new File("feide.xml"));
            trans.setInitialTemplate(new QName("main"));
            trans.setDestination(out);
            trans.transform();
        } catch (SaxonApiException se) {
            throw new AppException("Problem with xsl transformation.", se);
        }
    }

}
